package com.lmy.springboot;

import com.lmy.springboot.bean.Cat;
import com.lmy.springboot.bean.Dog;
import com.lmy.springboot.bean.Monster;
import com.lmy.springboot.config.BeanConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


/**
 * SpringbootApplication 注解用来标识这是一个springboot项目
 * 1.默认主程序所在的包及其子包下的所有文件会被扫描
 * 2.scanBasePackages = {"com.lmy", "com"} 指定springboot要指定的包及子包
 * 3.如果有多个包，可以 {"xxx","yyy"} 数组指定
 * 4.除了注解去修改配置，还可以通过文件去修改配置
 * 5.ConfigFileApplicationListener类会在项目启动时读取配置文件，配置文件的扫描路径和默认文件名(application)作为常量属性存储在该类中。file:指项目根目录下
 *   private static final String DEFAULT_SEARCH_LOCATIONS = "classpath:/,classpath:/config/,file:./,file:./config/星号/,file:./config/";
 *   private static final String DEFAULT_NAMES = "application";
*/
@SpringBootApplication(scanBasePackages = {"com.lmy", "com"})
public class MainApp {

    public static void main(String[] args) {

        //启动springboot应用程序/项目
        ConfigurableApplicationContext ioc
                = SpringApplication.run(MainApp.class, args);

        /*
            查看ioc容器中注入的组件
         */
        //查看ioc容器中注入的组件
//        String[] beanDefinitionNames = ioc.getBeanDefinitionNames();
//        for (String beanDefinitionName : beanDefinitionNames) {
//            System.out.println(beanDefinitionName);
//        }

        /*
        spring传统注解依然可以使用 @Controller @Service @Repository @Component等
         */
        //注解方式获取bean
//        Object bean = ioc.getBean("a");
//        System.out.println(bean.getClass());

        /*
            获取传统方式(beans.xml)配置的bean
         */
        //获取传统方式(beans.xml)配置的bean
//        ApplicationContext classPathXmlApplicationContext
//                = new ClassPathXmlApplicationContext("beans.xml");
//        Object bean = classPathXmlApplicationContext.getBean("monster01");
//        System.out.println(bean);

        /*
            springboot自带的Configuration注解完成bean的配置、注入
         */
        //获取monster_nmw
//        Monster monster1 = ioc.getBean("monster_nmw", Monster.class);
//        Monster monster2 = ioc.getBean("monster_nmw", Monster.class);
        //单例
//        System.out.println("monster1: " + monster1 + " " + "hash=" + monster1.hashCode());
//        System.out.println("monster2: " + monster2 + " " + "hash=" + monster2.hashCode());

        /*
            @Configuration(proxyBeanMethods = false)的作用
         */
        //获取配置类
//        BeanConfig bean = ioc.getBean(BeanConfig.class);
//        Monster monster1 = bean.monster02();
//        Monster monster2 = bean.monster02();
//        System.out.println("monster1: " + monster1 + " " + "hashcode: " + monster1.hashCode());
//        System.out.println("monster2: " + monster2 + " " + "hashcode: " + monster2.hashCode());

        /*
            springboot中可以有多个@Configuration配置类
         */
        //springboot中可以有多个@Configuration配置类
//        Monster monster03 = ioc.getBean("monster03", Monster.class);
//        System.out.println(monster03);

        /*
            @Import注入bean
         */
        //使用@Import注入bean
//        Dog dog = ioc.getBean(Dog.class);
//        Cat cat = ioc.getBean(Cat.class);
//        System.out.println("dogBean--" + dog);
//        System.out.println("catBean--" + cat);

        /*
            使用@ConditionalOnBean条件注入bean
         */
        //没有注入dog01的 Dog bean ，会报错
//        Dog bean = ioc.getBean("dog01", Dog.class);
//        System.out.println(bean);

        /*
            使用@ImportResource导入bean配置文件
         */
        //beans.xml配置的monster01
//        Monster monster01 = ioc.getBean("monster01", Monster.class);
//        System.out.println(monster01);

        /*
            判断容器中是否有某个bean
         */
        //ioc.containsBean("BeanName")
//        System.out.println("monster01是否存在-" + (ioc.containsBean("monster01") ? "是" : "否"));
    }
}
